package com.xhl.browser.domain;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.QueryHint;
import java.util.List;

import static org.hibernate.jpa.QueryHints.HINT_COMMENT;

/**
 * @author 徐宏亮
 * @description
 * @date 2018/12/29 14:07
 */
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
    /**
     * 功能描述 根据lastName查询结果，语义相当于`select * from customer where last_name=${lastName}`
     * @author 徐宏亮
     * @param lastName
     * @return java.util.List<com.shop.domain.Customer>
     * @throws
     */
    List<Customer> findByLastName(String lastName);

    /**
     * 功能描述 根据lastName查询倒叙结果
     * @author 徐宏亮
     * @param lastName
     * @return java.util.List<com.shop.domain.Customer>
     * @throws
     */
    @Query("select c from Customer c where c.lastName = ?1 order by c.id desc")
    List<Customer> findByLastName2(String lastName);

    /**
     * 功能描述 一个参数，匹配两个字段，这里Param的值和=:后面的参数匹配，但不需要和方法名对应的参数值对应
     * @author 徐宏亮
     * @param name2
     * @param sort 指定排序的参数，可以根据需要进行调整
     * @return java.util.List<com.shop.domain.Customer>
     * @throws
     */
    @Query("select c from Customer c where c.firstName=:name or c.lastName=:name")
    List<Customer> findByName(@Param("name") String name2, Sort sort);

    /**
     * 功能描述 根据lastName去更新firstName，返回结果是更改数据的行数
     * 更新查询、开启事务
     * @author 徐宏亮
     * @param firstName
     * @param lastName
     * @return int
     * @throws
     */
    @Modifying
    @Transactional(rollbackFor = Exception.class)
    @Query("update Customer c set c.firstName = ?1 where c.lastName = ?2")
    int setFixedFirstnameFor(String firstName, String lastName);

    /**
     * 功能描述 一个参数，匹配两个字段
     * 这里Param的值和=:后面的参数匹配，但不需要和方法名对应的参数值对应
     * 这里增加了@QueryHints注解，是给查询添加一些额外的提示
     * 比如当前的name值为HINT_COMMENT是在查询的时候带上一些备注信息
     * @author 徐宏亮
     * @param name
     * @param pageable
     * @return org.springframework.data.domain.Page<com.shop.domain.Customer>
     * @throws
     */
    @QueryHints(value = { @QueryHint(name = HINT_COMMENT, value = "a query for pageable")})
    @Query("select c from Customer c where c.firstName=:name or c.lastName=:name")
    Page<Customer> findByName2(@Param("name") String name, Pageable pageable);

    /**
     * 功能描述 这里没有用 Customer 接收，因为我们只需要特定的值即可。
     * @author 徐宏亮
     * @param
     * @return java.util.Collection<com.shop.domain.CustomerProjection>
     * @throws
     */
    @Query("select c.firstName as firstName, c.lastName as lastName from Customer  c")
    List<CustomerProjection> findAllProjectedBy();
}
